home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagd_f.zip / DIRS.SWG / 0026_DOS Directory Routines.pas < prev    next >
Pascal/Delphi Source File  |  1994-02-15  |  12KB  |  516 lines

  1.  
  2. { Updated DIRS.SWG on February 15, 1994 }
  3.  
  4. Unit PDir;
  5.  
  6. (*
  7.  
  8.    Palcic Directory Routines
  9.    Copyright (C) 1989, Matthew J. Palcic
  10.    Requires Turbo Pascal 5.5 or higher
  11.  
  12.    v1.0, 18 Aug 89 - Original release.
  13.  
  14. *)
  15.  
  16.  
  17. INTERFACE
  18.  
  19. uses Dos,Objects;
  20.  
  21. (*------------------------------------------------------------------------*)
  22.  
  23. TYPE
  24.  
  25.   AttrType = Byte;
  26.   FileStr = String[12];
  27.  
  28.   BaseEntryPtr = ^BaseEntry;
  29.   BaseEntry = object(Node)
  30.     Attr: AttrType;
  31.     Time: Longint;
  32.     Size: Longint;
  33.     Name: FileStr;
  34.     constructor Init;
  35.     destructor Done; virtual;
  36.     procedure ConvertRec(S:SearchRec);
  37.     function FileName: FileStr; virtual;
  38.     function FileExt: ExtStr; virtual;
  39.     function FullName: PathStr; virtual;
  40.     function FileTime: Longint; virtual;
  41.     function FileAttr: AttrType; virtual;
  42.     function FileSize: Longint; virtual;
  43.     function IsDirectory: Boolean;
  44.     constructor Load(var S: Stream);
  45.     procedure Store(var S: Stream); virtual;
  46.     end;
  47.  
  48.   FileEntryPtr = ^FileEntry;
  49.   FileEntry = object(BaseEntry)
  50.     constructor Init;
  51.     destructor Done; virtual;
  52.     procedure ForceExt(E:ExtStr);
  53.     procedure ChangeName(P:PathStr); virtual;
  54.      (* Change the name in memory *)
  55.     procedure ChangePath(P:PathStr); virtual;
  56.     procedure ChangeTime(T:Longint); virtual;
  57.     procedure ChangeAttr(A:AttrType); virtual;
  58.     procedure Erase; virtual;
  59.     function Rename(NewName:PathStr): Boolean; virtual;
  60.      (* Physically rename file on disk, returns False if Rename fails *)
  61.     function ResetTime: Boolean;
  62.     function ResetAttr: Boolean;
  63.     function SetTime(T:Longint): Boolean; virtual;
  64.     function SetAttr(A:AttrType): Boolean; virtual;
  65.     constructor Load(var S: Stream);
  66.     procedure Store(var S: Stream); virtual;
  67.     end;
  68.  
  69.   DirEntryPtr = ^DirEntry;
  70.   DirEntry = object(FileEntry)
  71.     DirEntries: List;
  72.     constructor Init;
  73.     constructor Clear;
  74.     destructor Done; virtual;
  75.     procedure FindFiles(FileSpec: FileStr; Attrib: AttrType);
  76.     procedure FindDirectories(FileSpec: FileStr; Attrib: AttrType);
  77.     constructor Load(var S: Stream);
  78.     procedure Store(var S: Stream); virtual;
  79.     end;
  80.  
  81.   DirStream = object(DosStream)
  82.     procedure RegisterTypes; virtual;
  83.     end;
  84.  
  85. function ExtensionPos(FName : PathStr): Word;
  86. function CurDir: PathStr;
  87. function ReadString(var S: Stream): String;
  88. procedure WriteString(var S: Stream; Str: String);
  89.  
  90. (*------------------------------------------------------------------------*)
  91.  
  92. IMPLEMENTATION
  93.  
  94.   (*--------------------------------------------------------------------*)
  95.   (* Methods for BaseEntry                                               *)
  96.   (*--------------------------------------------------------------------*)
  97.  
  98.   constructor BaseEntry.Init;
  99.     begin
  100.     end;
  101.  
  102.   destructor BaseEntry.Done;
  103.     begin
  104.     end;
  105.  
  106.   procedure BaseEntry.ConvertRec;
  107.     begin
  108.     Name := S.Name;
  109.     Size := S.Size;
  110.     Time := S.Time;
  111.     Attr := S.Attr;
  112.     end;
  113.  
  114.   function BaseEntry.FileName;
  115.     begin
  116.     FileName := Name;
  117.     end;
  118.  
  119.   function BaseEntry.FullName;
  120.     begin
  121.     FullName := Name;
  122.     end;
  123.  
  124.   function BaseEntry.FileExt;
  125.     var
  126.       ep: word;
  127.     begin
  128.     ep := ExtensionPos(Name);
  129.     if ep > 0 then
  130.       FileExt := Copy(Name, Succ(ep), 3)
  131.     else
  132.       FileExt[0] := #0;
  133.   end;
  134.  
  135.  
  136.   function BaseEntry.FileAttr;
  137.     begin
  138.     FileAttr := Attr;
  139.     end;
  140.  
  141.   function BaseEntry.FileSize;
  142.     begin
  143.     FileSize := Size;
  144.     end;
  145.  
  146.   function BaseEntry.FileTime;
  147.     begin
  148.     FileTime := Time;
  149.     end;
  150.  
  151.   function BaseEntry.IsDirectory;
  152.     begin
  153.     IsDirectory := (FileAttr and Dos.Directory) = Dos.Directory;
  154.     end;
  155.  
  156.   constructor BaseEntry.Load;
  157.     begin
  158.     S.Read(Attr,SizeOf(Attr));
  159.     S.Read(Time,SizeOf(Time));
  160.     S.Read(Size,SizeOf(Size));
  161.     Name := ReadString(S);
  162.     end;
  163.  
  164.   procedure BaseEntry.Store;
  165.     begin
  166.     S.Write(Attr,SizeOf(Attr));
  167.     S.Write(Time,SizeOf(Time));
  168.     S.Write(Size,SizeOf(Size));
  169.     WriteString(S,Name);
  170.     end;
  171.  
  172.   (*--------------------------------------------------------------------*)
  173.   (* Methods for FileEntry                                              *)
  174.   (*--------------------------------------------------------------------*)
  175.  
  176.   constructor FileEntry.Init;
  177.     begin
  178.     BaseEntry.Init; (* Call ancestor's Init *)
  179.     Name := '';
  180.     Size := 0;
  181.     Time := $210000; (* Jan. 1 1980, 12:00a *)
  182.     Attr := $00;  (* ReadOnly  = $01;
  183.                      Hidden    = $02;
  184.                      SysFile   = $04;
  185.                      VolumeID  = $08;
  186.                      Directory = $10;
  187.                      Archive   = $20;
  188.                      AnyFile   = $3F; *)
  189.     end;
  190.  
  191.   destructor FileEntry.Done;
  192.     begin
  193.     BaseEntry.Done;
  194.     end;
  195.  
  196.   function FileEntry.Rename;
  197.     var
  198.       F: File;
  199.     begin
  200.     Assign(F,FullName);
  201.     System.Rename(F,NewName); (* Explicit call to 'System.Rename' avoid
  202.                                  calling method 'FileEntry.Rename' *)
  203.     if IOResult = 0 then
  204.       begin
  205.       ChangePath(NewName);
  206.       Rename := True;
  207.       end
  208.     else
  209.       Rename := False;
  210.     end;
  211.  
  212.   procedure FileEntry.ForceExt;
  213.     var
  214.       ep: Word;
  215.       TempBool: Boolean;
  216.     begin
  217.     ep := ExtensionPos(FullName);
  218.     if ep > 0 then
  219.       TempBool := Rename(Concat(Copy(FullName, 1, ep),FileExt))
  220.     else
  221.       TempBool := Rename(Concat(FullName,'.',FileExt));
  222.     end;
  223.  
  224.   procedure FileEntry.ChangeName;
  225.     begin
  226.     Name := P;
  227.     end;
  228.  
  229.   procedure FileEntry.ChangePath;
  230.     begin
  231.     Name := P;  (* FileEntry object does not handle path *)
  232.     end;
  233.  
  234.   procedure FileEntry.ChangeTime;
  235.     begin
  236.     Time := T;
  237.     end;
  238.  
  239.   procedure FileEntry.ChangeAttr;
  240.     begin
  241.     Attr := A;
  242.     end;
  243.  
  244.   procedure FileEntry.Erase;
  245.     var
  246.       F:File;
  247.     begin
  248.     Assign(F,FullName);
  249.     Reset(F);
  250.     System.Erase(F); (* Remove ambiguity about 'Erase' call *)
  251.     Close(F);
  252.     end;
  253.  
  254.   function FileEntry.ResetTime;
  255.     var
  256.       F:File;
  257.     begin
  258.     Assign(F,FullName);
  259.     Reset(F);
  260.     SetFTime(F,FileTime);
  261.     ResetTime := IOResult = 0;
  262.     Close(F);
  263.     end;
  264.  
  265.   function FileEntry.SetTime;
  266.     var
  267.       F:File;
  268.     begin
  269.     Assign(F,FullName);
  270.     Reset(F);
  271.     SetFTime(F,T);
  272.     SetTime := IOResult = 0;
  273.     Close(F);
  274.     end;
  275.  
  276.   function FileEntry.ResetAttr;
  277.     var
  278.       F:File;
  279.     begin
  280.     Assign(F,FullName);
  281.     SetFAttr(F,FileAttr);
  282.     ResetAttr := IOResult = 0;
  283.     end;
  284.  
  285.   function FileEntry.SetAttr;
  286.     var
  287.       F:File;
  288.     begin
  289.     ChangeAttr(A);
  290.     SetAttr := ResetAttr;
  291.     end;
  292.  
  293.   constructor FileEntry.Load;
  294.     begin
  295.     BaseEntry.Load(S);
  296.     end;
  297.  
  298.   procedure FileEntry.Store;
  299.     begin
  300.     BaseEntry.Store(S);
  301.     end;
  302.  
  303.   (*--------------------------------------------------------------------*)
  304.   (* Methods for DirEntry                                               *)
  305.   (*--------------------------------------------------------------------*)
  306.  
  307.   constructor DirEntry.Init;
  308.     var
  309.       TempNode: Node;
  310.     begin
  311.     FileEntry.Init;
  312.     DirEntries.Delete;
  313.     end;
  314.  
  315.   destructor DirEntry.Done;
  316.     begin
  317.     DirEntries.Delete;
  318.     FileEntry.Done;
  319.     end;
  320.  
  321.   constructor DirEntry.Clear;
  322.     begin
  323.     DirEntries.Clear;
  324.     Init;
  325.     end;
  326.  
  327.   procedure DirEntry.FindFiles;
  328.     var
  329.       DirInfo: SearchRec;
  330.       TempFile: FileEntryPtr;
  331.     begin
  332.     FindFirst(FileSpec,Attrib,DirInfo);
  333.     while (DosError = 0) do
  334.       begin
  335.       TempFile := New(FileEntryPtr,Init);
  336.       TempFile^.ConvertRec(DirInfo);
  337.       DirEntries.Append(TempFile);
  338.       FindNext(DirInfo);
  339.       end;
  340.     end;
  341.  
  342.   procedure DirEntry.FindDirectories;
  343.     var
  344.       DirInfo: SearchRec;
  345.       TempDir: DirEntryPtr;
  346.     begin
  347.  
  348.     if FileSpec <> '' then
  349.       FindFiles(FileSpec,Attrib and not Dos.Directory);
  350.  
  351.     FindFirst('*.*',Dos.Directory,DirInfo);
  352.     while (DosError = 0) do
  353.       begin
  354.       if (DirInfo.Name[1] <> '.') and
  355.          ((DirInfo.Attr and Dos.Directory) = Dos.Directory) then
  356.          { if first character is '.' then name is either '.' or '..' }
  357.         begin
  358.         TempDir := New(DirEntryPtr,Clear);
  359.         TempDir^.ConvertRec(DirInfo);
  360.         DirEntries.Append(TempDir);
  361.         end;
  362.       FindNext(DirInfo);
  363.       end;
  364.  
  365.     TempDir := DirEntryPtr(DirEntries.First);
  366.     while TempDir <> nil do
  367.       begin
  368.       if TempDir^.IsDirectory then
  369.         begin
  370.         ChDir(TempDir^.FileName);
  371.         TempDir^.FindDirectories(FileSpec,Attrib);
  372.         ChDir('..');
  373.         end;
  374.       TempDir := DirEntryPtr(DirEntries.Next(TempDir));
  375.       end;
  376.     end;
  377.  
  378.   constructor DirEntry.Load;
  379.     begin
  380.     FileEntry.Load(S);
  381.     DirEntries.Load(S);
  382.     end;
  383.  
  384.   procedure DirEntry.Store;
  385.     begin
  386.     FileEntry.Store(S);
  387.     DirEntries.Store(S);
  388.     end;
  389.  
  390.   (*--------------------------------------------------------------------*)
  391.   (* Methods for DirStream                                               *)
  392.   (*--------------------------------------------------------------------*)
  393.  
  394.   procedure DirStream.RegisterTypes;
  395.     begin
  396.     DosStream.RegisterTypes;
  397.     Register(TypeOf(BaseEntry),@BaseEntry.Store,@BaseEntry.Load);
  398.     Register(TypeOf(FileEntry),@FileEntry.Store,@FileEntry.Load);
  399.     Register(TypeOf(DirEntry),@DirEntry.Store,@DirEntry.Load);
  400.     end;
  401.  
  402. (*---------------------------------------------------------------------*)
  403. (*  Miscellaneous Unit procedures and functions                        *)
  404. (*---------------------------------------------------------------------*)
  405.  
  406. function ExtensionPos;
  407.   var
  408.     Index: Word;
  409.   begin
  410.   Index := Length(FName)+1;
  411.   repeat
  412.     dec(Index);
  413.     until (FName[Index] = '.') OR (Index = 0);
  414.   IF (Pos('\', Copy(FName, Succ(Index), SizeOf(FName))) <> 0) THEN Index := 0;
  415.   ExtensionPos := Index;
  416.   end;
  417.  
  418. function CurDir;
  419.   var
  420.     P: PathStr;
  421.   begin
  422.   GetDir(0,P); { 0 = Current drive }
  423.   CurDir := P;
  424.   end;
  425.  
  426. function ReadString;
  427.   var
  428.     T: String;
  429.     L: Byte;
  430.  
  431.   begin
  432.   S.Read(L, 1);
  433.   T[0] := Chr(L);
  434.   S.Read(T[1], L);
  435.   IF S.Status = 0 then
  436.     ReadString := T
  437.   else
  438.     ReadString := '';
  439.   end;
  440.  
  441. procedure WriteString;
  442.   begin
  443.   S.Write(Str, Length(Str) + 1);
  444.   end;
  445.  
  446. (* No initialization code *)
  447. end.
  448.  
  449. {===============================    DEMO ============================ }
  450.  
  451. program PDTest;
  452.  
  453. uses Objects,PDir,Dos;
  454.  
  455. var
  456.   DP: DirEntryPtr;
  457.   St: DirStream;
  458.   Orig: PathStr;
  459.  
  460. procedure ProcessDir(D: DirEntryPtr; DirName: PathStr);
  461.   var
  462.     DirPtr : DirEntryPtr;
  463.   begin
  464.   DirPtr := DirEntryPtr(D^.DirEntries.First);
  465.   while DirPtr <> nil do
  466.     begin
  467.     if DirPtr^.IsDirectory then
  468.       ProcessDir(DirPtr,DirName+'\'+DirPtr^.FileName)
  469.       {recursively process subdirectories}
  470.     else
  471.       WriteLn(DirName+'\'+DirPtr^.FileName);
  472.     DirPtr := DirEntryPtr(D^.DirEntries.Next(DirPtr));
  473.     end;
  474.   end;
  475.  
  476.  
  477.  
  478. begin
  479. Orig := CurDir;
  480. WriteLn('Palcic''s File Finder v1.0');
  481.  
  482. if ParamCount = 0 then { Syntax is incorrect }
  483.   begin
  484.   WriteLn;
  485.   WriteLn('Syntax: PFF filespec');
  486.   WriteLn;
  487.   WriteLn('Directory names can not be passed.');
  488.   WriteLn;
  489.   WriteLn('Example: PFF *.ZIP');
  490.   WriteLn;
  491.   Halt;
  492.   end;
  493.  
  494. ChDir('C:\');
  495. New(DP,Clear);
  496.  
  497. WriteLn;
  498. Write('Scanning for ',ParamStr(1),'...');
  499. DP^.FindDirectories(ParamStr(1),Archive);
  500. WriteLn;
  501. WriteLn;
  502.  
  503. ProcessDir(DP,'C:');
  504.  
  505. WriteLn;
  506. WriteLn('Back to original directory ',Orig);
  507. ChDir(Orig);
  508.  
  509. St.Init('PFF.DAT',SCreate);
  510. DP^.Store(St);
  511. St.Done;
  512.  
  513. Dispose(DP,Done);
  514.  
  515. end.
  516.